#include "modelMgr.h"

/*
=============
struct Md5Model
=============
*/
Md5Model::Md5Model()
{
	md5mesh = new Md5Mesh;
	mapAnim.clear();
}

Md5Model::~Md5Model()
{
	delete md5mesh;

	auto itr = mapAnim.begin();
	while( itr != mapAnim.end() )
	{
		delete itr->second;
		++itr;
	}
	mapAnim.clear();
}

Md5Anim* Md5Model::GetAnim( string animname )
{
	auto itr = mapAnim.find( animname );
	if( itr == mapAnim.end() ){
		ERRBOX( "Md5Model , no this animname\n" );
	}
	return itr->second;
}

string Md5Model::GetShader( int iMesh )
{
	return md5mesh->vecMesh[ iMesh ].shader;
}

void Md5Model::PushAnim( Md5Anim* pAnim, string animname )
{
	if( mapAnim.find( animname ) == mapAnim.end() )
	{
		mapAnim.insert( make_pair( animname, pAnim ) );
	}
}

/*
===============
class cModelMgr
===============
*/

cModelMgr gModelMgr;


cModelMgr::cModelMgr()
{
	mapModels.clear();
	m_pMtr = new Mtr;
}

void cModelMgr::OnInit()
{
	m_pMd5Viewer = GetMd5Viewer();

	m_pMd5Viewer->ReadMtr( *m_pMtr, "../../files/md5Model/material/char_common.mtr" );
	m_pMd5Viewer->ReadMtr( *m_pMtr, "../../files/md5Model/material/characters.mtr" );
	m_pMd5Viewer->ReadMtr( *m_pMtr, "../../files/md5Model/material/kentest.mtr" );
	m_pMd5Viewer->ReadMtr( *m_pMtr, "../../files/md5Model/material/monsters.mtr" );
	m_pMd5Viewer->ReadMtr( *m_pMtr, "../../files/md5Model/material/senetemp.mtr" );
	m_pMd5Viewer->ReadMtr( *m_pMtr, "../../files/md5Model/material/weapons.mtr" );
	return;
}

void cModelMgr::PushModel( string modelfiles, string modelKey )
{
	if( mapModels.find( modelfiles ) != mapModels.end() )
		return;

	Md5Model* pMd5Mdl = ReadFiles( modelfiles );
	mapModels.insert( make_pair( modelKey, pMd5Mdl ) );
}

Md5Model* cModelMgr::GetModel( string modelkey )
{
	return mapModels[ modelkey ];
}

string cModelMgr::GetMeshShader( string shader )
{
	return m_pMtr->mapDiffuse[ shader ];
}

void cModelMgr::Release()
{
	auto itr = mapModels.begin();
	while( itr != mapModels.end() )
	{
		SAFE_DELETE( itr->second );
		++itr;
	}

	SAFE_DELETE( m_pMtr );
}

Md5Model* cModelMgr::ReadFiles( string modelfiles )
{
	Md5Model* pMd5Mdl = new Md5Model;
	
	modelfiles += "/";

	HANDLE hFile;
	WIN32_FIND_DATAA win32fd;
	string tmpFile = modelfiles;

	//find md5anim files
	tmpFile += "*.md5anim";

	hFile = FindFirstFileA( tmpFile.c_str(), &win32fd );
	if( INVALID_HANDLE_VALUE == hFile)
	{
		ERRBOX( "Read Model Files Failed" );
	}

	do {	
		Md5Anim* pAnim = new Md5Anim;
		m_pMd5Viewer->ReadMd5Anim( *pAnim, modelfiles + win32fd.cFileName );

		pMd5Mdl->PushAnim( pAnim, win32fd.cFileName );
	}
	while( FindNextFileA( hFile, &win32fd ) != 0 );

	FindClose( hFile );

	//find md5mesh file
	tmpFile = modelfiles;
	tmpFile += "*.md5mesh";

	hFile = FindFirstFileA( tmpFile.c_str(), &win32fd );
	if( INVALID_HANDLE_VALUE == hFile)
	{
		ERRBOX( "Read Model Files Failed" );
	}
	m_pMd5Viewer->ReadMd5Mesh( *pMd5Mdl->md5mesh, modelfiles + win32fd.cFileName );

	FindClose( hFile );

	return pMd5Mdl;
}


//////////////////////////////////////////////////////////////////////////

cModelMgr* GetModelMgr()
{
	return &gModelMgr;
}